package com.justgame.project.cloud.common.constant;

import com.alibaba.fastjson.JSONObject;
import com.justgame.project.cloud.common.util.HttpContextUtil;
import lombok.Data;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * ResponseBody结果集
 *
 * @param <T>
 */
@Data
public class Result<T> implements Serializable {
    private final static long serialVersionUID = Const.V;

    private boolean success = false;
    private String message = "操作失败!";
    private Integer code = 500;
    private T data;
    private String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    private long costTime;

    public static <T> Result<T> status(Boolean bool) {
        Result<T> result = new Result<>();
        if (bool) {
            return result.success();
        } else {
            return result.error();
        }
    }
    public static <T> Result<T> status(Integer integer) {
        Result<T> result = new Result<>();
        if (integer >= 1) {
            return result.success();
        } else {
            return result.error();
        }
    }

    public static <T> Result<T> status(Boolean bool, String message) {
        Result<T> result = new Result<>();
        if (bool) {
            return result.success(message);
        } else {
            return result.error(message);
        }
    }

    public static <T> Result<T> ok() {
        Result<T> result = new Result<>();
        return result.success();
    }

    public static <T> Result<T> ok(String message) {
        Result<T> result = new Result<>();
        return result.success(message);
    }

    public static <T> Result<T> ok(T data) {
        Result<T> result = new Result<>();
        return result.success(data);
    }

    public static <T> Result<T> ok(String message, Integer code) {
        Result<T> result = new Result<>();
        return result.success(message, code);
    }

    public static <T> Result<T> ok(String message, T data) {
        Result<T> result = new Result<>();
        return result.success(message, 200, data);
    }

    public static <T> Result<T> ok(String message, Integer code, T data) {
        Result<T> result = new Result<>();
        return result.success(message, code, data);
    }

    public static <T> Result<T> fail(String message, Integer code) {
        Result<T> result = new Result<>();
        return result.error(message, code);
    }

    public static <T> Result<T> fail(String message) {
        Result<T> result = new Result<>();
        return result.error(message);
    }

    public static <T> Result<T> fail() {
        Result<T> result = new Result<>();
        return result.error();
    }

    public boolean isSuccess() {
        return success;
    }

    public String getMessage() {
        return message;
    }

    public Integer getCode() {
        return code;
    }

    public T getData() {
        return data;
    }

    public void setCostTime(long costTime) {
        this.costTime = costTime;
    }

    public long getCostTime() {
        return costTime;
    }

    public String getTimestamp() {
        return timestamp;
    }

    private static long getCost() {
        try{
            HttpServletRequest request = HttpContextUtil.getHttpRequest();
            return System.currentTimeMillis() - (long) request.getAttribute(Const.REQUEST_START_TIME);
        }catch (Exception e){
            return -1;
        }
    }

    public Result<T> success() {
        this.success = true;
        this.message = "成功";
        this.code = 200;
        this.costTime = getCost();
        return this;
    }

    public Result<T> success(String message) {
        this.success = true;
        this.message = message;
        this.code = Const.RES_COMMON_SUCCESS;
        this.costTime = getCost();
        return this;
    }

    public Result<T> success(T data) {
        this.success = true;
        this.message = "成功";
        this.code = Const.RES_COMMON_SUCCESS;
        this.data = data;
        this.costTime = getCost();
        return this;
    }

    public Result<T> success(String message, Integer code) {
        this.success = true;
        this.message = message;
        this.code = code;
        this.costTime = getCost();
        return this;
    }

    public Result<T> success(String message, Integer code, T data) {
        this.success = true;
        this.message = message;
        this.code = code;
        this.data = data;
        this.costTime = getCost();
        return this;
    }

    public Result<T> error(String message, Integer code) {
        this.message = message;
        this.code = code;
        this.costTime = getCost();
        return this;
    }

    public Result<T> error(String message) {
        this.message = message;
        this.code = Const.RES_COMMON_ERROR;
        this.costTime = getCost();
        return this;
    }

    public Result<T> error() {
        this.costTime = getCost();
        return this;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }

}
